package mysql

import (
	"github.com/go-xorm/xorm"
	"github.com/pkg/errors"
)

//func (h *Handler) transactionWork(infos []*SqlInfo, auroraMode ...string) (values []int64, err error) {
//	for i := 0; i < 3; i++ {
//		if values, err = h.transaction(infos, auroraMode...); err != nil && strings.Contains(err.Error(), "1792") {
//			logger.Debug("transactionWork error", zap.Error(err), zap.Int("count", i), zap.Any("infos", infos))
//			time.Sleep(1 * time.Second)
//			continue
//		} else {
//			return
//		}
//	}
//	return
//}

func (h *Handler) transactionWork(infos []*SqlInfo, auroraMode ...string) (values []int64, err error) {
	// 判断引擎
	if h.EngineGroup == nil && h.Engine == nil {
		return values, errors.New("pretreatment：xorm engine cannot be empty")
	}
	// 获取 xorm 操作会话
	var session *xorm.Session
	if h.EngineGroup != nil {
		session = h.EngineGroup.NewSession()
	} else {
		session = h.Engine.NewSession()
	}
	defer session.Close()
	// 设置 aurora 的写入转发模式
	if auroraMode != nil {
		session, err = h.setAuroraReplicaReadConsistency(session, auroraMode[0])
		if err != nil {
			return
		}
	}
	// 开启事务
	if err = session.Begin(); err != nil {
		return
	}
	// 遍历 SQL 信息并执行
	values = make([]int64, 0)
	for _, info := range infos {
		// 预处理
		client, err := h.pretreatment(info, session)
		if err != nil {
			_ = session.Rollback()
			return nil, err
		}
		// 执行操作
		affected, err := action(client, info)
		if err != nil {
			//logger.Error("transaction part error ", zap.Error(err), zap.Any("info", info))
			_ = session.Rollback()
			return nil, err
		}
		// 构建响应结果
		values = append(values, affected)
	}
	// 提交事务
	err = session.Commit()
	return
}

func action(client *xorm.Session, info *SqlInfo) (affected int64, err error) {
	switch info.Func {
	case "Insert":
		affected, err = client.Insert(info.Obj)
	case "Update":
		affected, err = client.Update(info.Obj)
		if affected > 100 {
			return affected, errors.New("update：the number of affected lines exceeds 100 lines")
		}
	case "Delete":
		affected, err = client.Delete(info.Obj)
		if affected > 100 {
			return affected, errors.New("delete：the number of affected lines exceeds 100 lines")
		}
	default:
		err = errors.New("transaction：sql func is invalid —— " + info.Func)
	}
	return
}
